package com.openlogic.common.rabbitmq.util;

import java.io.UnsupportedEncodingException;

import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;

import com.openlogic.common.rabbitmq.config.properties.RabbitProperties;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmq.client.GetResponse;

import cn.hutool.core.util.StrUtil;

@Configuration
public class RabbitMqUtil {
	
	@Inject
	private ConnectionFactory connectionFactory;
	
	@Inject
	private RabbitProperties rabbitProperties;
	
	/**
	* 描述：获取系统环境前缀
	* @Title: rabbitMQEvn
	* @return
	* @author weiyongpeng
	* @date  2024年12月28日 上午10:05:48
	 */
    @Bean("rabbitMQEvn")
    public String rabbitMQEvn() {
        return getEvnPrefix();
    }

    private String getEvnPrefix() {
        return rabbitProperties.getEvnPrefix();
    }

    private String getEvnPrefix(String key) {
        return getEvnPrefix() + key;
    }
	
    /**
    * 描述：发送消息
    * @Title: convertAndSend
    * @param exchangeName 交换机名称
    * @param routingKey routingKey
    * @param msg 消息体
    * @throws Exception
    * @author weiyongpeng
    * @date  2025年1月22日 下午9:29:27
     */
	public void convertAndSend(String exchangeName, String routingKey, String msg) throws Exception {
		Connection connection =  connectionFactory.newConnection();
		Channel channel = connection.createChannel();
		//发送
        AMQP.BasicProperties msgProperties = new AMQP.BasicProperties();
        msgProperties.builder().contentEncoding("UTF-8");
        channel.basicPublish(getEvnPrefix(exchangeName), getEvnPrefix(routingKey), msgProperties, msg.getBytes());
    }
    
    /**
     * 根据队列名称消费消息
     *
     * @param queueName queueName
     * @return String message
     */
    public String receiveMessageByQueueName(String queueName, String exchangeName, String routingKey) {

        GetResponse responseMessage = null;
        Connection connection = null;
        Channel channel = null;
        try {
            //  获取连接
            try {
            	connection =  connectionFactory.newConnection();
			} catch (Exception e) {
				e.printStackTrace();
			}
            //  创建频道
            channel = connection.createChannel();
            //  自动确认消息
            boolean autoAck = true;
            String evnName = rabbitProperties.getEvnPrefix();
            // 声明一个Queue
            queueName = StrUtil.format("{}{}", evnName, queueName);
            //  队列声明
            channel.queueDeclare(queueName, true, false, false, null);
            channel.queueBind(queueName, getEvnPrefix(exchangeName), getEvnPrefix(routingKey));

            responseMessage = channel.basicGet(queueName, autoAck);

        } catch (Exception e) {
            e.printStackTrace();
        } 

        //  定义返回结果数据
        String result = "";
        if (null != responseMessage) {
            try {
				result = new String(responseMessage.getBody(), "UTF-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
        }
        return result;

    }

    /**
     * 根据队列名称消费消息-手动应答
     *
     * @param queueName queueName
     * @return String message
     */
    public String receiveMessageByQueueNameManualOperationACK(String queueName) throws Exception {

        Connection connection = null;
        Channel channel = null;
        final String[] results = {""};
        connection = connectionFactory.newConnection();

        channel = connection.createChannel();
        System.out.println("等待接收消息....");
        //推送的消息如何进行消费的接口回调
        Channel finalChannel = channel;
        try {
            DeliverCallback deliverCallback = (consumerTag, delivery) -> {
                String message = new String(delivery.getBody());
                System.out.println("接收到的消息" + message);
                results[0] = message;
                finalChannel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
            };
            //取消消费的一个回调接口 如在消费的时候队列被删除掉了
            CancelCallback cancelCallback = (consumerTag) -> {
                System.out.println("消息消费被中断");
            };
            channel.basicConsume(queueName, false, deliverCallback, cancelCallback);
        }catch (Exception e){
            e.printStackTrace();
        }
        return results[0];
    }

}
